/**
 * 摄像头权限引导页 Web Component (H5 环境)
 * 用法: <camera-permission-guide auto-check="true"></camera-permission-guide>
 *
 * 工作流程：
 * 1. 组件挂载后，如果 auto-check="true"，会自动检测摄像头权限
 * 2. 使用浏览器的 navigator.mediaDevices.getUserMedia() API 检测权限
 * 3. 如果有权限，触发 'permission-granted' 事件并隐藏组件
 * 4. 如果没有权限，显示引导页面并触发 'permission-denied' 事件
 * 5. 用户点击"开启权限"按钮，尝试请求摄像头权限
 */
class CameraPermissionGuide extends HTMLElement {
    constructor() {
        super();
        this.attachShadow({ mode: 'open' });
        this._hasPermission = false;
        this._isChecking = false;
        this._mediaStream = null;
    }

    static get observedAttributes() {
        return ['visible', 'title', 'description', 'auto-check', 'auto-remove'];
    }

    connectedCallback() {
        this.render();
        this.setupEventListeners();

        // 默认自动检测权限（除非明确设置为 false）
        const autoCheck = this.getAttribute('auto-check');
        if (autoCheck !== 'false') {
            setTimeout(() => this.checkPermission(), 100);
        }
    }

    disconnectedCallback() {
        console.log('🔌 [camera-permission-guide] 组件从 DOM 中移除');
        // 组件移除时自动释放摄像头资源
        this.releaseMediaStream();
    }

    attributeChangedCallback(name, oldValue, newValue) {
        if (oldValue !== newValue) {
            if (name === 'visible') {
                this.updateVisibility();
            } else {
                // 其他属性变化时可能需要更新内容
                this.updateContent();
            }
        }
    }

    updateVisibility() {
        const visible = this.getAttribute('visible') === 'true';
        this.style.display = visible ? 'block' : 'none';
    }

    updateContent() {
        const title = this.getAttribute('title') || '需要摄像头权限';
        const description =
            this.getAttribute('description') ||
            '为了给您提供更好的康复训练体验，请允许应用访问您的摄像头';

        const titleEl = this.shadowRoot.querySelector('.permission-title');
        const descEl = this.shadowRoot.querySelector('.permission-desc');

        if (titleEl) titleEl.textContent = title;
        if (descEl) descEl.textContent = description;
    }

    render() {
        const visible = this.getAttribute('visible') === 'true';
        const title = this.getAttribute('title') || '需要摄像头权限';
        const description =
            this.getAttribute('description') ||
            '为了给您提供更好的康复训练体验，请允许应用访问您的摄像头';

        this.shadowRoot.innerHTML = `
            <style>
                * {
                    box-sizing: border-box;
                }

                :host {
                    display: ${visible ? 'block' : 'none'};
                    position: fixed;
                    top: 0;
                    left: 0;
                    width: 100%;
                    height: 100vh;
                    height: 100dvh; /* 动态视口高度 */
                    z-index: 99999;
                }

                .error-toast {
                    position: fixed;
                    top: max(20px, env(safe-area-inset-top, 20px));
                    left: 50%;
                    transform: translateX(-50%);
                    background: rgba(239, 68, 68, 0.95);
                    color: white;
                    padding: clamp(12px, 3vw, 16px) clamp(16px, 4vw, 24px);
                    border-radius: 12px;
                    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3);
                    z-index: 100000;
                    display: none;
                    align-items: center;
                    gap: 12px;
                    max-width: 90%;
                    backdrop-filter: blur(10px);
                    animation: slideDown 0.3s ease-out;
                }

                .error-toast.show {
                    display: flex;
                }

                .error-icon {
                    font-size: clamp(20px, 5vw, 24px);
                    flex-shrink: 0;
                }

                .error-message {
                    font-size: clamp(13px, 3.5vw, 15px);
                    line-height: 1.5;
                }

                @keyframes slideDown {
                    from {
                        opacity: 0;
                        transform: translateX(-50%) translateY(-20px);
                    }
                    to {
                        opacity: 1;
                        transform: translateX(-50%) translateY(0);
                    }
                }

                .permission-guide {
                    display: flex;
                    flex-direction: column;
                    align-items: center;
                    justify-content: center;
                    width: 100%;
                    height: 100%;
                    padding: max(20px, env(safe-area-inset-top, 0)) 
                             max(20px, env(safe-area-inset-right, 0))
                             max(20px, env(safe-area-inset-bottom, 0))
                             max(20px, env(safe-area-inset-left, 0));
                    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
                    position: absolute;
                    top: 0;
                    left: 0;
                    overflow: hidden;
                }

                .permission-guide::before {
                    content: '';
                    position: absolute;
                    top: -50%;
                    left: -50%;
                    width: 200%;
                    height: 200%;
                    background: radial-gradient(circle, rgba(255, 255, 255, 0.1) 0%, transparent 70%);
                    transform: rotate(30deg);
                }

                .permission-content {
                    display: flex;
                    flex-direction: column;
                    align-items: center;
                    text-align: center;
                    z-index: 2;
                    width: 90%;
                    max-width: 500px;
                    margin: auto;
                }

                .permission-icon-wrapper {
                    margin-bottom: 12vw;
                    animation: float 3s ease-in-out infinite;
                }

                .permission-icon-bg {
                    width: 20vw;
                    height: 20vw;
                    min-width: 80px;
                    min-height: 80px;
                    max-width: 120px;
                    max-height: 120px;
                    background: linear-gradient(135deg, #10b981 0%, #059669 100%);
                    border-radius: 50%;
                    display: flex;
                    justify-content: center;
                    align-items: center;
                    box-shadow: 0 10px 25px rgba(16, 185, 129, 0.4);
                }

                .camera-icon {
                    width: 50%;
                    height: 50%;
                    position: relative;
                }

                .camera-icon::before {
                    content: '';
                    position: absolute;
                    top: 50%;
                    left: 50%;
                    transform: translate(-50%, -50%);
                    width: 32px;
                    height: 24px;
                    border: 3px solid #fff;
                    border-radius: 6px;
                }

                .camera-icon::after {
                    content: '';
                    position: absolute;
                    top: 50%;
                    right: -4px;
                    transform: translateY(-50%);
                    width: 0;
                    height: 0;
                    border-top: 8px solid transparent;
                    border-bottom: 8px solid transparent;
                    border-left: 10px solid #fff;
                }

                .permission-title {
                    font-size: clamp(20px, 5vw, 28px);
                    font-weight: bold;
                    color: #fff;
                    margin-bottom: 4vw;
                    text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
                }

                .permission-desc {
                    font-size: clamp(14px, 3.5vw, 18px);
                    color: rgba(255, 255, 255, 0.9);
                    text-align: center;
                    margin-bottom: 10vw;
                    line-height: 1.6;
                    padding: 0 5%;
                }

                .permission-btn {
                    width: 100%;
                    max-width: 400px;
                    height: clamp(48px, 12vw, 56px);
                    background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);
                    color: #fff;
                    border: none;
                    border-radius: 999px;
                    font-size: clamp(16px, 4vw, 20px);
                    font-weight: bold;
                    box-shadow: 0 6px 18px rgba(245, 158, 11, 0.4);
                    cursor: pointer;
                    transition: all 0.3s ease;
                    display: flex;
                    justify-content: center;
                    align-items: center;
                    gap: 10px;
                    margin-bottom: 5vw;
                }

                .permission-btn:active {
                    transform: scale(0.95);
                    box-shadow: 0 3px 10px rgba(245, 158, 11, 0.4);
                }

                .gear-icon {
                    width: 20px;
                    height: 20px;
                    position: relative;
                    display: inline-block;
                }

                .gear-icon::before {
                    content: '⚙️';
                    font-size: 20px;
                }

                .btn-text {
                    color: #fff;
                    font-weight: bold;
                }

                .permission-note {
                    font-size: clamp(12px, 3vw, 14px);
                    color: rgba(255, 255, 255, 0.7);
                }

                @keyframes float {
                    0%, 100% {
                        transform: translateY(0);
                    }
                    50% {
                        transform: translateY(-15px);
                    }
                }

                /* 小屏幕设备适配 */
                @media (max-width: 480px) {
                    .permission-icon-wrapper {
                        margin-bottom: 40px;
                    }
                    
                    .permission-title {
                        margin-bottom: 16px;
                    }
                    
                    .permission-desc {
                        margin-bottom: 40px;
                    }
                    
                    .permission-btn {
                        margin-bottom: 20px;
                    }
                }
                
                /* 横屏适配 */
                @media (max-height: 600px) and (orientation: landscape) {
                    .permission-icon-wrapper {
                        margin-bottom: 20px;
                    }
                    
                    .permission-icon-bg {
                        width: 60px;
                        height: 60px;
                        min-width: 60px;
                        min-height: 60px;
                    }
                    
                    .permission-title {
                        font-size: 20px;
                        margin-bottom: 10px;
                    }
                    
                    .permission-desc {
                        font-size: 14px;
                        margin-bottom: 20px;
                    }
                    
                    .permission-btn {
                        height: 44px;
                        font-size: 16px;
                        margin-bottom: 10px;
                    }
                    
                    .permission-note {
                        font-size: 12px;
                    }
                }
            </style>

            <!-- 错误提示 Toast -->
            <div class="error-toast" id="errorToast">
                <span class="error-icon">⚠️</span>
                <span class="error-message" id="errorMessage"></span>
            </div>

            <div class="permission-guide">
                <div class="permission-content">
                    <div class="permission-icon-wrapper">
                        <div class="permission-icon-bg">
                            <div class="camera-icon"></div>
                        </div>
                    </div>
                    <div class="permission-title">${title}</div>
                    <div class="permission-desc">${description}</div>
                    <button class="permission-btn">
                        <span class="gear-icon"></span>
                        <span class="btn-text">开启摄像头权限</span>
                    </button>
                    <div class="permission-note">您可以在设置中随时更改权限</div>
                </div>
            </div>
        `;
    }

    /**
     * 显示错误提示
     */
    showError(message, duration = 3000) {
        const errorToast = this.shadowRoot.getElementById('errorToast');
        const errorMessage = this.shadowRoot.getElementById('errorMessage');

        if (errorToast && errorMessage) {
            errorMessage.textContent = message;
            errorToast.classList.add('show');

            // 自动隐藏
            setTimeout(() => {
                errorToast.classList.remove('show');
            }, duration);
        }
    }

    setupEventListeners() {
        const btn = this.shadowRoot.querySelector('.permission-btn');
        if (btn) {
            btn.addEventListener('click', () => {
                console.log('🔓 [camera-permission-guide] 开启权限按钮被点击');
                // 尝试请求摄像头权限
                this.requestCameraPermission();
            });
        }
    }

    /**
     * 检测摄像头权限
     */
    async checkPermission() {
        if (this._isChecking) return;

        this._isChecking = true;
        console.log('🔍 [camera-permission-guide] 开始检测摄像头权限');

        try {
            // 检查浏览器是否支持
            if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
                const message = '您的浏览器不支持摄像头功能';
                console.error('❌ [camera-permission-guide]', message);
                this.showError(message);
                this.handlePermissionResult(false, 'NotSupportedError');
                return;
            }

            // 尝试获取摄像头权限（不显示视频，只是检测权限）
            const stream = await navigator.mediaDevices.getUserMedia({
                video: { facingMode: 'user' },
                audio: false
            });

            // 获取成功，保存流以便后续使用
            this._mediaStream = stream;
            this.handlePermissionResult(true);
        } catch (error) {
            console.log('❌ [camera-permission-guide] 权限检测失败:', error.name);
            this.handlePermissionResult(false, error.name);
        } finally {
            this._isChecking = false;
        }
    }

    /**
     * 请求摄像头权限
     */
    async requestCameraPermission() {
        console.log('📹 [camera-permission-guide] 请求摄像头权限');

        try {
            const stream = await navigator.mediaDevices.getUserMedia({
                video: { facingMode: 'user' },
                audio: false
            });

            this._mediaStream = stream;
            this.handlePermissionResult(true);
        } catch (error) {
            console.error('❌ [camera-permission-guide] 权限请求失败:', error.name);

            let message = '无法访问摄像头';
            if (error.name === 'NotAllowedError') {
                message = '您拒绝了摄像头权限，请在浏览器设置中允许访问';
            } else if (error.name === 'NotFoundError') {
                message = '未检测到摄像头设备';
            } else if (error.name === 'NotReadableError') {
                message = '摄像头正被其他应用占用';
            }

            // 显示错误提示
            this.showError(message);

            // 触发权限错误事件
            this.dispatchEvent(
                new CustomEvent('permission-error', {
                    bubbles: true,
                    composed: true,
                    detail: { error: error.name, message }
                })
            );
        }
    }

    /**
     * 处理权限检测结果
     */
    handlePermissionResult(hasPermission, errorType = null) {
        this._hasPermission = hasPermission;

        console.log(
            `📋 [camera-permission-guide] 权限状态: ${hasPermission ? '已授权' : '未授权'}`
        );

        if (hasPermission) {
            // 有权限，触发事件
            this.dispatchEvent(
                new CustomEvent('permission-granted', {
                    bubbles: true,
                    composed: true,
                    detail: {
                        hasPermission: true
                        // 不再传递 stream，外部需要的话自己调用 getUserMedia
                    }
                })
            );

            // 权限检测完成，立即释放摄像头资源
            this.releaseMediaStream();

            // 默认移除组件（除非明确设置为 false）
            const autoRemove = this.getAttribute('auto-remove');
            if (autoRemove !== 'false') {
                // 延迟移除，确保事件先触发
                setTimeout(() => {
                    console.log('🗑️ [camera-permission-guide] 自动移除组件');
                    this.remove();
                }, 100);
            } else {
                this.setAttribute('visible', 'false');
            }
        } else {
            // 没有权限，显示引导页
            this.setAttribute('visible', 'true');
            this.dispatchEvent(
                new CustomEvent('permission-denied', {
                    bubbles: true,
                    composed: true,
                    detail: { errorType }
                })
            );
        }
    }

    /**
     * 释放媒体流
     */
    releaseMediaStream() {
        if (this._mediaStream) {
            this._mediaStream.getTracks().forEach(track => track.stop());
            this._mediaStream = null;
            console.log('🔴 [camera-permission-guide] 媒体流已释放');
        }
    }

    /**
     * 获取媒体流（供外部使用）
     */
    getMediaStream() {
        return this._mediaStream;
    }

    /**
     * 手动显示组件
     */
    show() {
        this.setAttribute('visible', 'true');
    }

    /**
     * 手动隐藏组件
     */
    hide() {
        this.setAttribute('visible', 'false');
    }

    /**
     * 重新检测权限
     */
    async recheckPermission() {
        this._isChecking = false;
        await this.checkPermission();
    }

    /**
     * 获取当前权限状态
     */
    getPermissionStatus() {
        return this._hasPermission;
    }
}

// 注册自定义元素
customElements.define('camera-permission-guide', CameraPermissionGuide);
